package dao.impl;

import core.BaseDao;
import dao.OrderDao;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import pojo.*;
import util.DruidUtil;
import util.MyMapListHandler;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class OrderDaoImpl extends BaseDao implements OrderDao {

    protected Connection connection;

    public OrderDaoImpl() {
        this.connection = DruidUtil.getConnection();
    }

    public void setConnection(Connection connection) {
        this.connection = connection;
    }

    public Connection getConnection() {
        return connection;
    }

    /**
     * 查找订单对象
     *
     * @param tableId
     * @return
     */
    @Override
    public Order findOrderByTableId(String tableId) {
        try {
            sql = "SELECT * FROM `order` WHERE table_id=? ORDER BY order_id DESC LIMIT 1";
            return queryRunner.query(sql, new BeanHandler<>(Order.class, rowProcessor), tableId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return new Order();
    }

    /**
     * 将订单支付时间设置为null
     * @param orderId
     * @return
     */
    @Override
    public Integer setOrderPayTimeNULL(String orderId) {
        try {
            sql = "UPDATE `order` SET order_pay_time=null WHERE order_id = ?";
            return queryRunner.update(sql,orderId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 根据订单id删除订单信息
     * @param orderId
     * @return
     */
    @Override
    public Integer deleteOrderByOrderId(String orderId) {

        try {
            sql = "DELETE FROM `order` WHERE order_id = ?";
            return queryRunner.update(sql,orderId);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return 0;
    }

    /**
     * 查询今天的已支付订单
     *
     * @param today
     * @return
     */
    @Override
    public List<Order> findOrderByDay(String today) {
        try {
            sql = "SELECT * FROM `order` WHERE DATE(order_pay_time)= ?";
            List<Map<String, Object>> query = queryRunner.query(sql, new MyMapListHandler(), today);
            List<Order> orderList = new ArrayList<>();
            for (Map<String, Object> objectMap : query) {
                Order bean = new Order();
                BeanUtils.populate(bean, objectMap);
                orderList.add(bean);
            }
            return orderList;
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }

    /**
     * 通过日期查找营业额
     *
     * @param day
     * @return
     */
    @Override
    public String findOrderMoneyByDay(String day) {
        try {
            sql = "SELECT * FROM `order` WHERE DATE(order_pay_time)= ?";
            List<Order> query = queryRunner.query(sql, new BeanListHandler<>(Order.class, rowProcessor), day);
            if (query == null) {
                return "0";
            } else {
                Double money = 0.00;
                for (Order order : query) {
                    if (order != null && order.getOrderMoney()!=null) {
                        money=addDouble(money,order.getOrderMoney());
                    }
                }
                return money.toString();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 根据订单查找所有对象数量
     * @param order
     * @return
     */
    @Override
    public Integer countOrderList(Order order) {
        sql = "SELECT COUNT(1) FROM `order` WHERE order_pay_time IS NOT NULL AND order_money>0";
        List<String> paramList = new ArrayList<>();
        if (order.getOrderMemberName() != null && !order.getOrderMemberName().isEmpty()) {
            sql += " AND order_member_name LIKE ?";
            paramList.add("%" + order.getOrderMemberName() + "%");
        }
        if (order.getOrderWorkerName() != null && !order.getOrderWorkerName().isEmpty()) {
            sql += " AND order_worker_name LIKE ?";
            paramList.add("%" + order.getOrderWorkerName() + "%");
        }
        if (order.getOrderIsMember() != null && order.getOrderIsMember() != 2) {
            sql += " AND order_is_member = ?";
            paramList.add(order.getOrderIsMember().toString());
        }

        if (paramList.size() == 3) {
            try {
                return Integer.valueOf(queryRunner.query(sql, new ScalarHandler<>(), paramList.get(0), paramList.get(1), paramList.get(2)).toString());
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } else if (paramList.size() == 2) {
            try {
                return Integer.valueOf(queryRunner.query(sql, new ScalarHandler<>(), paramList.get(0), paramList.get(1)).toString());
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } else if (paramList.size() == 1) {
            try {
                return Integer.valueOf(queryRunner.query(sql, new ScalarHandler<>(), paramList.get(0)).toString());
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } else {
            try {
                return Integer.valueOf(queryRunner.query(sql, new ScalarHandler<>()).toString());
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return 0;
    }

    /**
     * 根据订单查找所有对象
     *
     * @param order
     * @return
     */
    @Override
    public List<Order> orderList(Order order) {
        sql = "SELECT * FROM `order` WHERE order_pay_time IS NOT NULL AND order_money>0";
        List<String> paramList = new ArrayList<>();
        if (order.getOrderMemberName() != null && !order.getOrderMemberName().isEmpty()) {
            sql += " AND order_member_name LIKE ?";
            paramList.add("%" + order.getOrderMemberName() + "%");
        }
        if (order.getOrderWorkerName() != null && !order.getOrderWorkerName().isEmpty()) {
            sql += " AND order_worker_name LIKE ?";
            paramList.add("%" + order.getOrderWorkerName() + "%");
        }
        if (order.getOrderIsMember() != null && order.getOrderIsMember() != 2) {
            sql += " AND order_is_member = ?";
            paramList.add(order.getOrderIsMember().toString());
        }

        sql += " ORDER BY order_pay_time DESC LIMIT ?,?";

        Integer page = (order.getPage() - 1) * order.getLimit();
        Integer limit = order.getLimit();

        if (paramList.size() == 3) {
            try {
                return queryRunner.query(sql, new BeanListHandler<>(Order.class, rowProcessor), paramList.get(0), paramList.get(1), paramList.get(2), page, limit);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } else if (paramList.size() == 2) {
            try {
                return queryRunner.query(sql, new BeanListHandler<>(Order.class, rowProcessor), paramList.get(0), paramList.get(1), page, limit);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } else if (paramList.size() == 1) {
            try {
                return queryRunner.query(sql, new BeanListHandler<>(Order.class, rowProcessor), paramList.get(0), page, limit);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } else {
            try {
                return queryRunner.query(sql, new BeanListHandler<>(Order.class, rowProcessor), page, limit);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return new ArrayList<>();
    }

    /***
     * 更新会员支付的信息
     * @param memberName
     * @param workerName
     * @return
     */
    @Override
    public Integer updateMemberInfo(String memberName, String workerName, String orderId) {
        try {
            sql = "UPDATE `order` SET order_member_name=?,order_worker_name=? WHERE order_id=?";
            return queryRunner.update(sql, memberName, workerName, orderId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 修改订单支付为会员支付类型
     *
     * @param orderId
     * @return
     */
    @Override
    public Integer updateOrderIsMember(String orderId) {
        try {
            sql = "UPDATE `order` SET order_is_member=1 WHERE order_id=?";
            return queryRunner.update(sql, orderId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 通过订单Id查找订单
     *
     * @param orderId
     * @return
     */
    @Override
    public Order findOrderById(String orderId) {
        try {
            sql = "SELECT * FROM `order` WHERE order_id=?";
            return queryRunner.query(sql, new BeanHandler<>(Order.class, rowProcessor), orderId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return new Order();
    }

    /**
     * 非会员支付修改订单支付
     *
     * @param orderId
     * @return
     */
    @Override
    public Integer normalPay(String orderId) {
        try {
            sql = "UPDATE `order` SET order_pay_time=? WHERE order_id=?";
            return queryRunner.update(sql, new Timestamp(System.currentTimeMillis()), orderId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 修改订单的总金额
     *
     * @param orderId
     * @param orderMoney
     * @return
     */
    @Override
    public Integer updateOrderMoney(String orderId, String orderMoney) {
        try {
            sql = "UPDATE `order` SET order_money=?,order_pay_time=? WHERE order_id=?";
            return queryRunner.update(sql, orderMoney, new Timestamp(System.currentTimeMillis()), orderId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 查找详细的订单对象
     *
     * @param tableId
     * @param orderId
     * @return
     */
    @Override
    public List<Order> findDetailOrderByTableId(String tableId, String orderId) {
        try {
            sql = "SELECT * FROM `order` o, order_food of, table_info ti WHERE o.order_id=of.order_id AND o.table_id=ti.table_id AND o.table_id=? AND o.order_id=? GROUP BY of.order_food_id";
            List<Map<String, Object>> query = queryRunner.query(sql, new MyMapListHandler(), tableId, orderId);
            List<Order> orderList = new ArrayList<>();
            TableInfo tableInfo = new TableInfo();
            for (Map<String, Object> objectMap : query) {
                Order order = new Order();
                BeanUtils.populate(order, objectMap);
                BeanUtils.populate(tableInfo, objectMap);
                OrderFood orderFood = new OrderFood();
                BeanUtils.populate(orderFood, objectMap);
                sql = "SELECT * FROM food f, order_food of WHERE f.food_id=of.food_id AND f.food_id=?";
                Food food = queryRunner.query(sql, new BeanHandler<>(Food.class, rowProcessor), orderFood.getFoodId());
                orderFood.setFood(food);
                order.setTableInfo(tableInfo);
                order.setOrderFood(orderFood);
                sql = "SELECT * FROM `order` o, order_food_bk ofb WHERE o.order_id=ofb.order_id AND o.order_id=? AND ofb.food_id=? GROUP BY ofb.order_food_bk_id";
                List<Map<String, Object>> query2 = queryRunner.query(sql, new MyMapListHandler(), order.getOrderId(), orderFood.getFoodId());
                if (query2 != null) {
                    for (Map<String, Object> stringObjectMap : query2) {
                        OrderFoodBk orderFoodBk1 = new OrderFoodBk();
                        BeanUtils.populate(orderFoodBk1, stringObjectMap);
                        order.setOrderFoodBk(orderFoodBk1);
                    }
                }
                orderList.add(order);
            }
            return orderList;
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }

    /**
     * 查找餐桌的最新id
     *
     * @param tableId
     * @return
     */
    @Override
    public Integer findOrderIdByTableId(String tableId) {
        try {
            sql = "SELECT order_id FROM `order` WHERE table_id=? ORDER BY order_id DESC LIMIT 1";
            Object query = queryRunner.query(sql, new ScalarHandler<>(), tableId);
            if (query == null) {
                return 0;
            }
            return Integer.valueOf(query.toString());
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 生成一个订单
     *
     * @param order
     * @return
     */
    @Override
    public Integer add(Order order) {
        try {
            sql = "INSERT INTO `order`(table_id, order_create_time) VALUES (?,?)";
            return queryRunner.update(sql,
                    order.getTableId(),
                    new Timestamp(System.currentTimeMillis())
            );
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 普通支付
     * @param orderId
     * @param connection
     * @return
     */
    public Integer normalPay(String orderId, String orderWorkerName,Connection connection) {
        try {
            sql = "UPDATE `order` SET order_worker_name=? WHERE order_id=?";
            return queryRunner.update(connection, sql, orderWorkerName, orderId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 更新订单金额
     * @param orderId
     * @param orderMoney
     * @param connection
     * @return
     */
    public Integer updateOrderMoney(String orderId, String orderMoney, Connection connection) {
        try {
            sql = "UPDATE `order` SET order_money=?,order_pay_time=? WHERE order_id=?";
            return queryRunner.update(connection, sql, orderMoney, new Timestamp(System.currentTimeMillis()), orderId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 更新订单支付状态为会员支付
     * @param orderId
     * @param connection
     * @return
     */
    public Integer updateOrderIsMember(String orderId, Connection connection) {
        try {
            sql = "UPDATE `order` SET order_is_member=1 WHERE order_id=?";
            return queryRunner.update(connection, sql, orderId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 更改会员支付信息
     * @param memberName
     * @param workerName
     * @param orderId
     * @param connection
     * @return
     */
    public Integer updateMemberInfo(String memberName, String workerName, String orderId, Connection connection) {
        try {
            sql = "UPDATE `order` SET order_member_name=?,order_worker_name=? WHERE order_id=?";
            return queryRunner.update(connection, sql, memberName, workerName, orderId);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * double不丢精度加法计算
     * @param m1
     * @param m2
     * @return
     */
    public static double addDouble(double m1, double m2) {
        BigDecimal p1 = new BigDecimal(Double.toString(m1));
        BigDecimal p2 = new BigDecimal(Double.toString(m2));
        return p1.add(p2).doubleValue();
    }
}
